// @Author EthanScriptOn
// @Desc
package config_node

import (
	"errors"
	"gitee.com/fatzeng/srf_switch_basic_components/node"
	"gitee.com/fatzeng/srf_switch_config/config_define"
)

type ParseResultPackageNode struct {
	*node.DoublyLinkedNode
	group map[config_define.NodeElemType]interface{}
}

func GenerateParseResultPackageNode() *ParseResultPackageNode {
	parseResultPackageNode := new(ParseResultPackageNode)
	parseResultPackageNode.group = make(map[config_define.NodeElemType]interface{})
	dlList := node.GenerateEmptyDoublyLinkedNode(parseResultPackageNode)
	parseResultPackageNode.DoublyLinkedNode = dlList
	return parseResultPackageNode
}

func (p *ParseResultPackageNode) StoreGroupResult(elemType config_define.NodeElemType, elem interface{}) {
	p.group[elemType] = elem
}

func (p *ParseResultPackageNode) GetGroupResult() map[config_define.NodeElemType]interface{} {
	return p.group
}

func (p *ParseResultPackageNode) DeepCopy() *ParseResultPackageNode {
	node := GenerateParseResultPackageNode()
	originResult := p.GetGroupResult()
	for elemType, elemVal := range originResult {
		node.StoreGroupResult(elemType, elemVal)
	}
	return node
}

func (p *ParseResultPackageNode) LinkDeepCopy() (*ParseResultPackageNode, error) {
	currentDeepCopy := p.DeepCopy()
	preDeepCopy, err := p.preLinkDeepCopy()
	if err != nil {
		return nil, err
	}
	if preDeepCopy != nil {
		if err := preDeepCopy.SlotNode(node.TAIL, currentDeepCopy); err != nil {
			return nil, err
		}
	}
	afterDeepCopy, err := p.afterLinkDeepCopy()
	if err != nil {
		return nil, err
	}
	if afterDeepCopy != nil {
		if err := currentDeepCopy.SlotNode(node.TAIL, afterDeepCopy); err != nil {
			return nil, err
		}
	}
	return currentDeepCopy, nil
}

func (p *ParseResultPackageNode) preLinkDeepCopy() (*ParseResultPackageNode, error) {
	preNode, hasNode, err := p.GetAdjacentNode(node.HEAD)
	if err != nil {
		return nil, err
	}
	if !hasNode {
		return nil, nil
	}
	packageNode, ok := preNode.(*ParseResultPackageNode)
	if !ok {
		return nil, errors.New("preNode can not convert to *ParseResultPackageNode")
	}
	deepCopyPackageNode := packageNode.DeepCopy()
	preLinkDeepCopy, err := packageNode.preLinkDeepCopy()
	if err != nil {
		return nil, err
	}
	if preLinkDeepCopy == nil {
		return deepCopyPackageNode, nil
	}
	if err = deepCopyPackageNode.SlotNode(node.HEAD, preLinkDeepCopy); err != nil {
		return nil, err
	}
	return deepCopyPackageNode, nil
}

func (p *ParseResultPackageNode) afterLinkDeepCopy() (*ParseResultPackageNode, error) {
	afterNode, hasNode, err := p.GetAdjacentNode(node.TAIL)
	if err != nil {
		return nil, err
	}
	if !hasNode {
		return nil, nil
	}
	packageNode, ok := afterNode.(*ParseResultPackageNode)
	if !ok {
		return nil, errors.New("afterNode can not convert to *ParseResultPackageNode")
	}
	deepCopyPackageNode := packageNode.DeepCopy()
	afterLinkDeepCopy, err := packageNode.afterLinkDeepCopy()
	if err != nil {
		return nil, err
	}
	if afterLinkDeepCopy == nil {
		return deepCopyPackageNode, nil
	}
	if err = deepCopyPackageNode.SlotNode(node.TAIL, afterLinkDeepCopy); err != nil {
		return nil, err
	}
	return deepCopyPackageNode, nil
}
